/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tesis.common.util;

import java.util.ArrayList;
import java.util.*;
import tesis.domain.*;
import tesis.dto.in.*;
import tesis.dto.util.Constantes;

/**
 *
 * @author hugo
 */
public class MotorUtil {
    
    
    // Esta esta yuca 
    public static ArrayList<ArrayList<Regla>> ordenarReglas(List<Regla> lstReglas){
        
        
        
        ArrayList<ArrayList<Regla>> lstResult = new ArrayList<ArrayList<Regla>>();
        List<Integer> lstPosiciones = new ArrayList<Integer>();
        Integer posicionMayor = 0;
        for(Integer i= 0; i<=Constantes.CANTIDAD_MAX_NIVELES;i++) lstResult.add(new ArrayList<Regla>());
        
        Integer posicionRegla = -1;
        for(Regla regla : lstReglas){
           posicionRegla = getPosicionRegla(regla);
           if(posicionMayor<=posicionRegla) posicionMayor = posicionRegla;
           
           
           if(existePosicion(lstPosiciones,posicionRegla)){
               lstResult.get(posicionRegla).add(regla);
           }else{      
               lstResult.set(posicionRegla,new ArrayList<Regla>());
               lstResult.get(posicionRegla).add(regla);
               lstPosiciones.add(posicionRegla);
           }
        }
        ArrayList<ArrayList<Regla>> lstResultOrder = new ArrayList<ArrayList<Regla>>();
        for(Integer i= 0; i<=posicionMayor; i++) lstResultOrder.add(new ArrayList<Regla>());
        for(Integer i =0; i<=posicionMayor;i++)lstResultOrder.set(i,lstResult.get(i));
        return lstResultOrder;
    }
        
    private static Integer getPosicionRegla(Regla regla){
        Integer  respVariable[]  = {0,0};
        Integer respDocumento[] = {0,0};
        respVariable = getSaltosVariable(regla,respVariable);
        respDocumento = getSaltosDocumentos(regla, respDocumento) ;
        if(respVariable[1]>= respDocumento[1]){
            return respVariable[1];
        }else{
            return respDocumento[1];
        }

    } 
    
    
    private static Integer[] getSaltosVariable(Regla regla,   Integer[] total){
        Integer[] result = null ;
        List<ReglaXParametroVariable> lstregParVar = regla.getReglaXParametroVariableList();
        total[0] = 0;
        for(ReglaXParametroVariable regParVar:lstregParVar){
            
            if(regParVar.getEsentrada() == Constantes.SI && regParVar.getIdparamentrovariable().getReglaXParametroVariableList().size()>=2){
               ReglaXParametroVariable e =  regParVar.getIdparamentrovariable().getReglaXParametroVariableList().get(0);
               if(e.getIdregla().getIdregla().intValue() == regla.getIdregla().intValue()){
                   e =  regParVar.getIdparamentrovariable().getReglaXParametroVariableList().get(1);
               }
               result = getSaltosVariable(e.getIdregla(),total);
               total[0] = total[0] +1 + result[0];
               if(total[0].intValue()>=total[1].intValue()){
                   total[1] = total[0] ;
                   total[0] = 0;
                
               }
            }else{
                total[0] = 0; 
            }
                
        }
        return total ;
    }
    
    private static Integer[] getSaltosDocumentos(Regla regla,Integer[] total){
        Integer[] resp  = null;
        List<ReglaXParametroDocumento> lstregParDoc = regla.getReglaXParametroDocumentoList();
        total[0] = 0;
        for(ReglaXParametroDocumento regParDoc:lstregParDoc){
            if(regParDoc.getEsentrada() == Constantes.SI && regParDoc.getIdparametrodocumento().getReglaXParametroDocumentoList().size()>=2){
               ReglaXParametroDocumento e =  regParDoc.getIdparametrodocumento().getReglaXParametroDocumentoList().get(0);
               if(e.getIdregla().getIdregla().intValue() == regla.getIdregla().intValue()){
                   e =  regParDoc.getIdparametrodocumento().getReglaXParametroDocumentoList().get(1);
               }
               resp = getSaltosDocumentos(e.getIdregla(), total);
               total[0] = total[0] +1+ resp[0];
               if(total[0].intValue() >= total[1].intValue() ) {
                   total[1] = total[0];
                   total[0] = 0;
               }
            }else{
                total[0] = 0; 
            }     
        }
        return total;
    }
    
    
    private static boolean  existePosicion(List<Integer> lstPosiciones, Integer posicionRegla){
        boolean resp = false;
        for(Integer posicion:lstPosiciones){
            if(posicion.intValue() == posicionRegla.intValue()){
                resp = true;
            }
        }
        return resp;
    }
    
    
    
    
    //Obtiene los parametros variables para la regla 
    public static List<ParametroVariable> getParametroVariable(Regla regla){
        List<ParametroVariable> lstResult = new ArrayList<ParametroVariable>();
        List<ReglaXParametroVariable> lstParVar = regla.getReglaXParametroVariableList();
        for(ReglaXParametroVariable regParVar : lstParVar){
            lstResult.add(regParVar.getIdparamentrovariable());
        }        
        return lstResult;
    }
    
    public static List<ParametroDocumento> getParametroTipoDocumento( Regla regla){
        List<ParametroDocumento> lstResult = new ArrayList<ParametroDocumento>();
        List<ReglaXParametroDocumento> lstParDoc = regla.getReglaXParametroDocumentoList();
        for(ReglaXParametroDocumento regParDoc: lstParDoc) {
            lstResult.add(regParDoc.getIdparametrodocumento());
        }
        return lstResult;
    }
    
    
    public static boolean  esEntrada(ParametroVariable parVar, Regla regla){
        boolean result = true;
        List<ReglaXParametroVariable> lstParVar = regla.getReglaXParametroVariableList();
        for(ReglaXParametroVariable regParVar : lstParVar){
            if(parVar.getIdparamentrovariable().intValue()== regParVar.getIdparamentrovariable().getIdparamentrovariable().intValue()){
                if(regParVar.getEsentrada()== Constantes.SI){
                    result = true;
                }else{
                    result = false;
                }
            }
        }
        return result;
    }
    
    public static boolean esSalida(ParametroVariable parVar, Regla regla){
        boolean result = true;
        List<ReglaXParametroVariable> lstParVar = regla.getReglaXParametroVariableList();
        for(ReglaXParametroVariable regParVar : lstParVar){
            if(parVar.getIdparamentrovariable().intValue()== regParVar.getIdparamentrovariable().getIdparamentrovariable().intValue()){
                if(regParVar.getEsentrada()== Constantes.NO){
                    result = true;
                }else{
                    result = false;
                }
            }
        }
        return result;
    }
    
    public static boolean esEntrada(ParametroDocumento parDoc, Regla regla){
        boolean result = true;
        List<ReglaXParametroDocumento> lstParDoc = regla.getReglaXParametroDocumentoList();
        for(ReglaXParametroDocumento regParDoc: lstParDoc){
            if(parDoc.getIdparametrodocumento().intValue()== regParDoc.getIdparametrodocumento().getIdparametrodocumento().intValue()){
                if(regParDoc.getEsentrada()== Constantes.SI){
                    result = true;
                }else {
                    result = false;
                }
            }
        }
        return result;
    }
    
    public static boolean esSalida(ParametroDocumento parDoc, Regla regla){
        boolean result = true;
        List<ReglaXParametroDocumento> lstParDoc = regla.getReglaXParametroDocumentoList();
        for(ReglaXParametroDocumento regParDoc: lstParDoc){
            if(parDoc.getIdparametrodocumento().intValue()== regParDoc.getIdparametrodocumento().getIdparametrodocumento().intValue()){
                if(regParDoc.getEsentrada()== Constantes.NO){
                    result = true;
                }else {
                    result = false;
                }
            }
        }
        return result;
    }
    
    public static boolean  analizarVariable(ParametroVariable parVar, List<VariableDTO> lstVarDTO){
        boolean result = true;
        TipoComparacion tipoComparacion = parVar.getIdtipocomparacion();
        if(tipoComparacion.getNombre().equals(Constantes.ASIGNACION))  return true;
        for(VariableDTO varDTO : lstVarDTO){
            try{
                int e = parVar.getIdestacionvariable().getIdvariable().getIdvariable().intValue();
                if (parVar.getIdestacionvariable().getIdvariable().getIdvariable().intValue() == varDTO.getIdvariable().intValue()) {
                    String valorComparacionSTR = parVar.getValorcomparacion();
                    String valorVarDTOSTR = varDTO.getValorVariable();
                    TipoDato tipoDato = parVar.getIdestacionvariable().getIdvariable().getIdtipodato();
                    if (tipoDato.getCodigotipodato().equals(Constantes.ENTERO)) {
                        Integer valorComparacion =  Integer.parseInt(valorComparacionSTR);
                        Integer valorVarDTO = Integer.parseInt(valorVarDTOSTR);
                        result = compararVariable(valorVarDTO, valorComparacion, parVar.getIdtipocomparacion());
                    }
                    if (tipoDato.getCodigotipodato().equals(Constantes.CADENA)) {
                        result = compararVariable(valorVarDTOSTR,valorComparacionSTR , parVar.getIdtipocomparacion());
                    }
                    if (tipoDato.getCodigotipodato().equals(Constantes.REAL)) {
                        float valorComparacion = Float.parseFloat(valorComparacionSTR);
                        float valorVarDTO = Float.parseFloat(valorVarDTOSTR);
                        result = compararVariable(valorVarDTO, valorComparacion, parVar.getIdtipocomparacion());
                    }
                    if (tipoDato.getCodigotipodato().equals(Constantes.BOOLEAN)) {
                        boolean valorComparacion = Boolean.parseBoolean(valorComparacionSTR);
                        boolean valorVarDTO = Boolean.parseBoolean(valorVarDTOSTR);
                        result = compararVariable(valorVarDTO, valorComparacion, parVar.getIdtipocomparacion());
                    }
                    if (tipoDato.getCodigotipodato().equals(Constantes.ASIGNACION)){
                        result = true;
                    }
                }     
            }catch(Exception ex){
               String res = ex.toString();
            }
        }
        return result;
    }
    
    public static boolean deberiaAnalizarse(ParametroVariable parVar , boolean respExecution ){
        boolean resp = true;
        TipoComparacion tipoComparacion= parVar.getIdtipocomparacion();
        boolean condicionEvaluacion  =true ;
        if(parVar.getEsverdadera() == Constantes.SI) condicionEvaluacion = true;
        else condicionEvaluacion = false;       
        
        if(tipoComparacion.getNombre().equals(Constantes.ASIGNACION)) {
            if(condicionEvaluacion == respExecution){
                resp = true;
            }else resp = false;   
        }
        return resp;
    }
   
    public static boolean deberiaAnalizarse(ParametroDocumento parDoc, boolean respExecution ){
        boolean resp = true;
        TipoComparacion tipoComparacion= parDoc.getIdtipocomparacion();
        boolean condicionEvaluacion  =true ;
        if(parDoc.getEsverdadera() == Constantes.SI) condicionEvaluacion = true;
        else condicionEvaluacion = false;     
        
        if(tipoComparacion.getNombre().equals(Constantes.ASIGNACION)){
            if(condicionEvaluacion == respExecution){
                resp = true;
            }else resp = false;
        }
        
        return resp;
    }

    
    
    
    public static boolean analizarDocumento(ParametroDocumento parDoc, List<DocumentoDTO> lstDocDTO) {
        boolean result = true;
        TipoComparacion tipoComparacion = parDoc.getIdtipocomparacion();
        if(tipoComparacion.getNombre().equals(Constantes.ASIGNACION))  return true;
        for(DocumentoDTO docDTO: lstDocDTO){
            if(parDoc.getIdestaciontipodocumento().getIdtipodocumento().getIdtipodocumento().intValue() == docDTO.getIdtipodocumentoDTO().getIdTipoDocumento().intValue()){
                Integer tDocVarDTO =  docDTO.getIdtipodocumentoDTO().getEstadoDocumento().getIdestadodocumento();
                Integer tDocComparacion = parDoc.getValorcomparacion().getIdestadodocumento();
                result = compararDocumento(tDocVarDTO, tDocComparacion,parDoc.getIdtipocomparacion());
            }
        }
        
        
        
        return result;
    }
    
    
    
    public static boolean analizarRegla(boolean  respAnterior, boolean respDato, Regla regla){
        boolean result = true;
        TipoRegla tipoRegla = regla.getIdtiporegla();
        if(tipoRegla.getNombre().equals(Constantes.AND)){
            result = respAnterior & respDato;
        }
        if(tipoRegla.getNombre().equals(Constantes.OR)){
            result = respAnterior  | respDato;
        }
        if(tipoRegla.getNombre().equals(Constantes.XOR)){
            result = respAnterior ^ respDato; 
        }
        return result;
    }
    
    public static InstanciaEstacionXParametroVariable getInsEstXParVar(ParametroVariable parVar, ExecuteStationDTO executeStationDTO,Regla regla){
        InstanciaEstacionXParametroVariable bean = new InstanciaEstacionXParametroVariable();
       
        bean.setFechamodificacion(new Date());
        bean.setIdinstanciaestacion(new InstanciaEstacion(executeStationDTO.getInstanciaDTO().getIdinstanciaestacion()));
        bean.setIdparamentrovariable(parVar);
        
        for(VariableDTO var : executeStationDTO.getLstVarDTO()){
            if(parVar.getIdestacionvariable().getIdvariable().getIdvariable().intValue()==var.getIdvariable().intValue()){
               if(esEntrada(parVar, regla)){
                   bean.setValorvariable(var.getValorVariable());
               }
               else{
                   if(esSalida(parVar, regla)){
                       bean.setValorvariable(parVar.getValoractualizado());
                       var.setValorVariable(parVar.getValoractualizado());
                   }
               }
               
                break;
            }
        }
        return bean;
    }
    
    public static InstanciaEstacionXParametroDocumento getInstEstXParDoc(ParametroDocumento parDoc,ExecuteStationDTO executeStationDTO,Regla regla){
        InstanciaEstacionXParametroDocumento bean = new InstanciaEstacionXParametroDocumento();
        bean.setFechamodificacion(new Date());
        bean.setIdparametrodocumento(parDoc);
        bean.setIdinstanciaestacion(new InstanciaEstacion(executeStationDTO.getInstanciaDTO().getIdinstanciaestacion()));
        bean.setIdestadodocumento(parDoc.getValoractualizado());
        for(DocumentoDTO doc: executeStationDTO.getLstDocumentoDTO()){
            if(parDoc.getIdestaciontipodocumento().getIdtipodocumento().getIdtipodocumento().intValue() == doc.getIdtipodocumentoDTO().getIdTipoDocumento().intValue() ){
               if(esEntrada(parDoc, regla)){
                   bean.setIdestadodocumento(ConvertBeanUtil.convertEstadoDocumentoDTOtoEntity( doc.getIdtipodocumentoDTO().getEstadoDocumento()));
                   bean.setIddocumento(new Documento(doc.getIddocumento()));
               }
               else{
                   if(esSalida(parDoc, regla)){
                       bean.setIdestadodocumento(parDoc.getValoractualizado());
                       bean.setIddocumento(new Documento(doc.getIddocumento()));
                       doc.getIdtipodocumentoDTO().setEstadoDocumento(ConvertBeanUtil.toEstadoDocumentoDTO(parDoc.getValoractualizado()));
                   }
               }
                
                
                break;
            }
        }
        return bean;
    }
    
    
    
    public static boolean existenConexionesAlternas(Regla regla){
        boolean result = true;
        if(regla.getConexionEstacionreglaList().size()>0){
            result = true;
        }else{
            result = false;
        }
        return result;
    }
    
    
    public static InstanciaEstacion getInstEstAlt(ConexionEstacionregla conEst,ExecuteStationDTO executeDTO,InstanciaProceso instProceso){
        InstanciaEstacion resul = new InstanciaEstacion();
         Estacion estacion = conEst.getIdestacion();
        resul.setFechacreacion(new Date());
        resul.setIdestacion(estacion);
        resul.setIdinstanciaproceso(instProceso);
        resul.setIdusuario(new Usuario(executeDTO.getInstanciaDTO().getUsuario().getIdusuario()));
        
        return resul;
    }
    
    
    public static boolean compararVariable(Integer varDTO, Integer varCompa, TipoComparacion tipoComp){
        boolean result = true;
        
        if(tipoComp.getNombre().equals(Constantes.IGUAL)){
            if(varDTO.intValue()==varCompa.intValue()) result = true;
            else result = false;
            
        }
        if(tipoComp.getNombre().equals(Constantes.DISTINTO)){
            if(varDTO.intValue()!=varCompa.intValue()) result = true;
            else result = false;
        }
        if(tipoComp.getNombre().equals(Constantes.MAYOR)){
            if(varDTO.intValue()>varCompa.intValue())result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MAYOR_IGUAL)){
            if(varDTO.intValue()>=varCompa.intValue())result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MENOR)){
            if(varDTO.intValue()<varCompa.intValue()) result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MENOR_IGUAL)){
            if(varDTO.intValue()<=varCompa.intValue())result = true;
            else result=false;
        }
        
        return result;
    }
    
      public static boolean compararVariable(float varDTO, float varCompa, TipoComparacion tipoComp){
        boolean result = true;
        
        if(tipoComp.getNombre().equals(Constantes.IGUAL)){
            if(varDTO==varCompa) result = true;
            else result = false;
            
        }
        if(tipoComp.getNombre().equals(Constantes.DISTINTO)){
            if(varDTO!=varCompa) result = true;
            else result = false;
        }
        if(tipoComp.getNombre().equals(Constantes.MAYOR)){
            if(varDTO>varCompa)result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MAYOR_IGUAL)){
            if(varDTO>=varCompa)result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MENOR)){
            if(varDTO<varCompa) result = true;
            else result=false;
        }
        if(tipoComp.getNombre().equals(Constantes.MENOR_IGUAL)){
            if(varDTO<=varCompa)result = true;
            else result=false;
        }
        
        return result;
    } 
      
    public static boolean compararVariable(String varDTO, String varCompa, TipoComparacion tipoComp){
        boolean result = true;
        
        if(tipoComp.getNombre().equals(Constantes.IGUAL)){
            if(varDTO.equals(varCompa)) result = true;
            else result = false;
            
        }
        if(tipoComp.getNombre().equals(Constantes.DISTINTO)){
            if(!varDTO.equals(varCompa)) result = true;
            else result = false;
        }
        return result;
    } 
    
    public static boolean compararVariable(boolean varDTO, boolean varCompa, TipoComparacion tipoComp){
        boolean result = true;
        
        if(tipoComp.getNombre().equals(Constantes.IGUAL)){
            if(varDTO==varCompa) result = true;
            else result = false;
            
        }
        if(tipoComp.getNombre().equals(Constantes.DISTINTO)){
            if(varDTO!=varCompa) result = true;
            else result = false;
        }
        return result;
    } 
      
    public static boolean compararDocumento(Integer tDocDTO , Integer tDocCompa,TipoComparacion tipoComp){
        boolean result = true;
        if(tipoComp.getNombre().equals(Constantes.IGUAL)){
            if(tDocDTO.intValue() ==tDocCompa.intValue()) result = true;
            else result = false;
        }
        if(tipoComp.getNombre().equals(Constantes.DISTINTO)){
            if(tDocDTO!=tDocCompa) result = true;
            else result = false;
        }
        return result;
    }
    
    public static boolean esUltimaEstacion(Estacion estacion){
        
        boolean resp = false;
        for(Conexion conexcion : estacion.getConexionListI()){
            if(conexcion.getIdestacionfin().getNombre().equals(Constantes.Estacion_FIN)){
                resp = true;
                break;
            } 
        }
        return resp;
    }  
    
    
    public static boolean esPrimeraEstacion(Estacion estacion){
        boolean resp = false;
        for(Conexion conexion: estacion.getConexionListF()){
            if(conexion.getIdestacioninicio().getNombre().equals(Constantes.Estacion_INICIO)){
                resp = true;
                break;
            }
        }
        return resp;
    }
    
    
    public static Estacion obtenerSiguienteEstacion(Estacion estacion){
        Estacion nuevaEstacion = new Estacion();
        for(Conexion conexion: estacion.getConexionListI()){
            if(conexion.getEsalterna()== Constantes.NO){
                nuevaEstacion = conexion.getIdestacionfin();
            }
        }
        return nuevaEstacion;
    }
    
    
    
}
